//http.ts
import axios, { AxiosProgressEvent } from 'axios'
import { message } from 'antd'
import { logout } from '@/utils/user'

// 设置请求头和请求路径
axios.defaults.timeout = 100000
axios.defaults.headers.post['Content-Type'] = 'application/json'
axios.interceptors.request.use(
  (config): any => {
    const token = window.localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  (error) => {
    return error
  }
)
// 响应拦截
axios.interceptors.response.use((res) => {
  if (res.data.status_code === 100003 || res.data.status_code === 100004) {
    res.data.error_info && message.error(res.data.error_info)
    setTimeout(() => {
      logout()
    }, 1000)
  } else if (res.data.status_code && res.data.status_code !== 0) {
    res.data.error_info && message.error(res.data.error_info)
    throw new Error(res.data.error_info)
  } else {
    return res.data
  }
})

interface Http {
  get<T>(url: string, params?: unknown): Promise<T>
  post<T>(url: string, params?: unknown): Promise<T>
  delete<T>(url: string, params?: unknown): Promise<T>
  upload<T>(
    url: string,
    params: unknown,
    onUploadProgress?: (progressEvent: AxiosProgressEvent) => void,
    signal?: AbortSignal
  ): Promise<T>
  download(url: string): void
  getStreamData(
    url: string,
    params?: unknown,
    callback?: (data: any) => void,
    signal?: AbortSignal
  ): Promise<any>
}

const http: Http = {
  get(url, params) {
    return new Promise((resolve, reject) => {
      axios
        .get(url, { params })
        .then((res) => {
          resolve(res.data)
        })
        .catch((err) => {
          reject(err.data)
        })
    })
  },
  post(url, params) {
    return new Promise((resolve, reject) => {
      axios
        .post(url, params)
        .then((res) => {
          resolve(res.data)
        })
        .catch((err) => {
          reject(err.data)
        })
    })
  },
  delete(url) {
    return new Promise((resolve, reject) => {
      axios
        .delete(url)
        .then((res) => {
          resolve(res.data)
        })
        .catch((err) => {
          reject(err.data)
        })
    })
  },
  upload(url, file, onUploadProgress?, signal?) {
    return new Promise((resolve, reject) => {
      axios
        .post(url, file, {
          headers: { 'Content-Type': 'multipart/form-data' },
          onUploadProgress,
          signal
        })
        .then((res) => {
          resolve(res.data)
        })
        .catch((err) => {
          reject(err.data)
        })
    })
  },
  download(url) {
    const iframe = document.createElement('iframe')
    iframe.style.display = 'none'
    iframe.src = url
    iframe.onload = function () {
      document.body.removeChild(iframe)
    }
    document.body.appendChild(iframe)
  },
  async getStreamData(
    url: string,
    params?: unknown,
    callback?: (data: any) => void,
    signal?: AbortSignal
  ) {
    return new Promise((resolve, reject) => {
      const token = localStorage.getItem('token')
      fetch(url, {
        method: 'POST',
        body: JSON.stringify(params),
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${token}`
        },
        signal
      })
        .then((res) => {
          const reader = res?.body?.getReader()
          if (!reader) {
            return
          }
          reader.read().then(function process({ done, value }): any {
            if (done) {
              resolve(res.body)
              return
            }
            if (!value) return
            const decoder = new TextDecoder()
            const dataString = decoder.decode(value)
            if (callback) {
              callback(dataString)
            }
            // console.log(dataString, '\n======================================')
            return reader.read().then(process)
          })
        })
        .catch((error) => {
          reject(error)
        })
    })
  }
}

export default http
